use opencv::prelude::*;
use opencv::{
    core,
    core::{Point, Scalar},
    imgcodecs,
    imgproc,
    Result,
    // highgui videoio,
};

pub fn test_template_match(template_name: &str, test_file_name: &str, debug: bool) -> Result<bool> {
    let mut image = imgcodecs::imread(test_file_name, imgcodecs::IMREAD_GRAYSCALE)?;
    let templ = imgcodecs::imread(template_name, imgcodecs::IMREAD_GRAYSCALE)?;
    template_match(&mut image, &templ, debug)
}

fn template_match(image: &mut Mat, templ: &Mat, debug: bool) -> Result<bool> {
    let now = std::time::Instant::now();
    // 创建结果矩阵
    let result_cols = image.cols() - templ.cols() + 1;
    let result_rows = image.rows() - templ.rows() + 1;
    let mut result = unsafe { Mat::new_rows_cols(result_rows, result_cols, core::CV_32FC1)? };

    // 进行模板匹配
    imgproc::match_template_def(image, templ, &mut result, imgproc::TM_CCOEFF_NORMED)?;

    let mut max_val = -1f64; //分数最大值
    let mut max_loc = Point::new(-1, -1); //最大值坐标

    core::min_max_loc(
        &result,
        Some(&mut 0f64),
        Some(&mut max_val),
        Some(&mut Point::default()),
        Some(&mut max_loc),
        &Mat::default(),
    )?;

    // 利用最大分数来判断是否存在模板>0.99
    // 可以遍历结果取出满足阈值的位置 参考以下代码
    // /async-demo202402/src/test/java/com/xue/opencv/ImageJOpenCVExample.java
    println!("maxval={},max_loc={:?}", &max_val, &max_loc);
    let elapsed = now.elapsed();
    println!("耗时: {:?}", elapsed);

    if debug {
        imgproc::rectangle_points_def(
            image,
            Point::new(max_loc.x, max_loc.y),
            Point::new(max_loc.x + templ.cols(), max_loc.y + templ.rows()),
            Scalar::new(255., 255., 255., 0.),
        )?;

        //opencv::highgui::imshow("Template ", templ)?;
        // 显示带有匹配结果的图像
        //opencv::highgui::imshow("Template Matching Result", image)?;
    }
    Ok(max_val >= 0.98)
}
/*
pub fn open_camera() -> Result<()> {
    use std::{thread, time};
    use winapi::um::winuser::{
        FindWindowA, GetSystemMetrics, GetWindowLongA, SetWindowLongA, SetWindowPos, GWL_STYLE,
        HWND_TOPMOST, SM_CXSCREEN, SM_CYSCREEN, SWP_NOMOVE, SWP_NOSIZE, WS_MAXIMIZEBOX,
        WS_MINIMIZEBOX, WS_SYSMENU,
    };

    let window_name = "bwexam";

    // 创建 OpenCV 窗口
    highgui::named_window(
        window_name,
        highgui::WINDOW_NORMAL | highgui::WINDOW_AUTOSIZE | highgui::WND_PROP_TOPMOST,
    )
    .unwrap();

    // 获取窗口句柄
    // https://blog.csdn.net/FairLikeSnow/article/details/108504299
    let hwnd = unsafe { FindWindowA(std::ptr::null_mut(), window_name.as_ptr() as *const i8) };
    if hwnd.is_null() {
        println!("无法找到窗口句柄！");
        // return;
    }

    //设置窗口为置顶
    unsafe {
        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    }

    // 获取当前窗口样式
    let style = unsafe { GetWindowLongA(hwnd, GWL_STYLE) };

    // 禁用最小化按钮
    let new_style = style & !WS_MINIMIZEBOX as i32 & !WS_MAXIMIZEBOX as i32 & !WS_SYSMENU as i32;
    unsafe {
        SetWindowLongA(hwnd, GWL_STYLE, new_style);
    }

    let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?; // 0 is the default camera
    let opened = videoio::VideoCapture::is_opened(&cam)?;
    if !opened {
        panic!("Unable to open default camera!");
    }
    loop {
        let mut frame = Mat::default();
        cam.read(&mut frame)?;
        if frame.size()?.width > 0 {
            highgui::imshow(window_name, &frame)?;
        }
        let key = highgui::wait_key(10)?;
        if key > 0 && key != 255 {
            break;
        }
    }
    Ok(())
}
    */
